package com.ruoyi.socket.handler;

import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.gams.device.led.LEDSender2010;
import com.ruoyi.gams.device.led.ScreenService;
import com.ruoyi.gams.domain.*;
import com.ruoyi.gams.mapper.*;
import com.ruoyi.socket.screen.ScreenVO;
import com.ruoyi.socket.server.SocketClientStore;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.List;

/**
 * 呼叫器消息解析
 */
@Component
@Slf4j
public class CallDeviceMessageHandler
{

    @Autowired
    private GamsDeviceMapper deviceMapper;

    @Autowired
    private GamsWindowMapper windowMapper;

    @Autowired
    private GamsUserQueueMapper userQueueMapper;

    @Autowired
    private SocketClientStore socketClientStore;

    @Autowired
    private GamsWindowTextMapper windowTextMapper;

    @Autowired
    private GamsStaffMapper staffMapper;

    @Autowired
    private RuoYiConfig ruoYiConfig;

    @Autowired
    private ScreenService screenService;

    public void getResultMsg(String msg)
    {
        if (StringUtils.isEmpty(msg))
        {
            log.info("msg is null");
            return;
        }
        //FF68030368 00 01 0C0D16
        String deviceId = msg.substring(10, 12);
        String command = msg.substring(14, msg.length() - 4);
        GamsDevice device = deviceMapper.findFirstByDeviceId(deviceId);
        if (device == null)
        {
            log.info("device is null");
            return;
        }
        deviceMapper.updateHeartTimeByDeviceId(new Date(), deviceId);

        GamsWindow window = windowMapper.findFirstByCallingDeviceId(device.getId());
        if (window == null)
        {
            log.info("window is null");
            return;
        }

        call(command, window);


    }

    public void call(String command, GamsWindow window)
    {
        GamsStaff staff = staffMapper.selectGamsStaffById(window.getStaffId());
        if (staff == null)
        {
            log.info("staff is null");
            return;
        }

        String cmd = command.substring(0, 2);
        String number = "";
        if (command.length() > 2)
        {
            number = command.substring(2);
        }
        switch (cmd)
        {
            //呼叫
            case "0C":
            {
                call(window);
                break;
            }
            //评价
            case "0B":
                evaluation(window, staff);
                break;
            //挂起
            case "14":
                hangup(window);
                break;
            //转移
            case "13":
                reback(window);
                break;
            //等候
            case "12":
                wait(window);
                break;
            //欢迎
            case "0A":
                welcome(window);
                break;
            //重呼
            case "0D":
                recall(window);
                break;
            //指定呼叫
            case "0F":
                callNumber(window, number);
                break;
        }
    }

    //转移
    private void reback(GamsWindow window)
    {
        //1.手头的号状态改成挂起
        GamsUserQueue lastUserqueue = userQueueMapper.findFirstByStaffIdAndStatus(window.getStaffId(), 2);
        if (lastUserqueue != null)
        {
            lastUserqueue.setStatus(1);
            userQueueMapper.updateGamsUserQueue(lastUserqueue);
        }
    }

    //挂起
    private void hangup(GamsWindow window)
    {
        //1.手头的号状态改成挂起
        GamsUserQueue lastUserqueue = userQueueMapper.findFirstByStaffIdAndStatus(window.getStaffId(), 2);
        if (lastUserqueue != null)
        {
            lastUserqueue.setStatus(3);
            userQueueMapper.updateGamsUserQueue(lastUserqueue);
        }
    }

    //指定呼叫
    private void callNumber(GamsWindow window, String number)
    {   //2.修改排队第一的号
        GamsUserQueue userQueue = userQueueMapper.findFirstByNumberOrderByIdDesc(number);
        if (userQueue == null)
        {
            log.info("未找到这个编号:" + number);
            return;
        }
        //3.修改当前号码状态
        userQueue.setStatus(2);
        userQueueMapper.updateGamsUserQueue(userQueue);

        //4.修改窗口屏显示
        GamsWindowText text = windowTextMapper.findFirstByWindowId(window.getId());
        text.setText("请" + userQueue.getNumber() + "办理业务");//暂停服务
        text.setInmethod(2);//静止状态
        windowTextMapper.updateGamsWindowText(text);

        //语音叫号
        sendVoice(window, userQueue);

        //更新综合屏
        sendSyncScreen(window, userQueue);

        screenService.refreshWindowScreen(window.getWindowScreenId(), LEDSender2010.ROOT_PLAY);
    }

    //重呼
    private void recall(GamsWindow window)
    {
        //1.手头的号
        GamsUserQueue userQueue = userQueueMapper.findFirstByWindowIdAndStatusOrderByIdDesc(window.getId(), 2);
        if (userQueue == null)
        {
            log.info("未找到这个窗口编号:" + window.getId());
            call(window);
            return;
        }

        //4.修改窗口屏显示
        GamsWindowText text = windowTextMapper.findFirstByWindowId(window.getId());
        text.setText("请" + userQueue.getNumber() + "办理业务");//暂停服务
        text.setInmethod(2);//静止状态
        windowTextMapper.updateGamsWindowText(text);

        //语音叫号
        sendVoice(window, userQueue);

        //更新综合屏
        sendSyncScreen(window, userQueue);

        screenService.refreshWindowScreen(window.getWindowScreenId(), LEDSender2010.ROOT_PLAY);
    }

    private void welcome(GamsWindow window)
    {
        //修改屏幕显示暂停服务
        GamsWindowText text = windowTextMapper.findFirstByWindowId(window.getId());
        text.setText("热情服务您");//暂停服务
        text.setInmethod(1);//静止状态
        windowTextMapper.updateGamsWindowText(text);

        screenService.refreshWindowScreen(window.getWindowScreenId(), LEDSender2010.ROOT_PLAY);
    }

    //暂停服务
    private void wait(GamsWindow window)
    {
        //修改屏幕显示暂停服务
        GamsWindowText text = windowTextMapper.findFirstByWindowId(window.getId());
        text.setText("暂停服务");//暂停服务
        text.setInmethod(1);//静止状态
        windowTextMapper.updateGamsWindowText(text);

        screenService.refreshWindowScreen(window.getWindowScreenId(), LEDSender2010.ROOT_PLAY);
    }

    //评价器登录
    private void evaluationLogin(GamsWindow window, GamsStaff staff)
    {
        JSONObject staffInfo = new JSONObject();//员工信息
        staffInfo.put("name", staff.getStaffName());//名称
        staffInfo.put("avtor", ruoYiConfig.getServerUrl() + staff.getAvtor());//头像
        staffInfo.put("job", staff.getJobName());//职位
        staffInfo.put("tel", "0755-42880122");//投诉电话
        staffInfo.put("staffNo", staff.getStaffNo());//员工编号

        GamsDevice scoringDevice = deviceMapper.selectGamsDeviceById(window.getScoringDeviceId());
        if (scoringDevice == null)
        {
            log.info("找不到评价器");
            return;
        }

        //评价器展示员工信息
        JSONObject page = new JSONObject();
        page.put("d", "S000001");//服务器设备ID
        page.put("c", "5");//1.登录 2.心跳 4.呼叫器指令 5.评价器指令
        page.put("page", "2");//评价器页面 1.首页 2.窗口工作人员信息页 3.评价页
        page.put("data", staffInfo);//数据内容（本指令中：员工信息JSON）
        String msg1 = JSONObject.toJSONString(page);
        log.info("msg1 = " + msg1);
        socketClientStore.send(scoringDevice.getDeviceId(), msg1);
    }

    private void evaluation(GamsWindow window, GamsStaff staff)
    {
        JSONObject data = new JSONObject();//员工信息
        data.put("name", staff.getStaffName());//名称
        data.put("avtor", ruoYiConfig.getServerUrl() + staff.getAvtor());//头像
        data.put("tel", "0755-42880122");//投诉电话
        data.put("staffNo", staff.getStaffNo());//员工编号
        data.put("job", staff.getJobName());//职位

        GamsUserQueue queue = userQueueMapper.findFirstByStaffIdAndStatus(staff.getId(), 2);
        data.put("queueNo", queue.getNumber());
        data.put("bussinessName", queue.getBussinessName());
        data.put("date", DateUtils.getTime());

        GamsDevice scoringDevice1 = deviceMapper.selectGamsDeviceById(window.getScoringDeviceId());
        if (scoringDevice1 == null)
        {
            log.info("找不到评价器");
            return;
        }
        //评价器展示员工信息
        JSONObject page1 = new JSONObject();
        page1.put("d", "S000001");//服务器设备ID
        page1.put("c", "5");//1.登录 2.心跳 4.呼叫器指令 5.评价器指令
        page1.put("page", "3");//评价器页面 1.首页 2.窗口工作人员信息页 3.评价页
        page1.put("data", data);//数据内容（本指令中：员工信息JSON）
        String msg2 = JSONObject.toJSONString(page1);
        log.info("msg2 = " + msg2);
        socketClientStore.send(scoringDevice1.getDeviceId(), msg2);
    }

    private void call(GamsWindow window)
    {
        //1.手头的号状态改成完成
        GamsUserQueue lastUserqueue = userQueueMapper.findFirstByWindowIdAndStatusOrderByIdDesc(window.getId(), 2);
        if (lastUserqueue != null)
        {
            lastUserqueue.setStatus(4);
            userQueueMapper.updateGamsUserQueue(lastUserqueue);
        }
        //2.修改排队第一的号
        String queueIds = window.getBusinessQueueIds();
        if (queueIds == null)
        {
            log.info("该窗口未绑定业务");
            return;
        }
        String[] ids = queueIds.split(",");
        //2.修改排队第一的号
        GamsUserQueue userQueue = userQueueMapper.findFirstByBussinessIdAndStatus(Integer.valueOf(ids[0]), 1);
        if (userQueue == null)
        {
            //4.修改窗口屏显示
            GamsWindowText text = windowTextMapper.findFirstByWindowId(window.getId());
            text.setText(text.getDefaultText());//暂停服务
            text.setInmethod(1);//静止状态
            windowTextMapper.updateGamsWindowText(text);

            //窗口屏显示
            screenService.refreshWindowScreen(window.getWindowScreenId(), LEDSender2010.ROOT_PLAY);
            return;
        }
        //3.修改当前号码状态
        userQueue.setStatus(2);
        userQueue.setStaffId(window.getStaffId());
        userQueue.setStaffName(window.getStaffName());
        userQueue.setWindowNum(window.getName());
        userQueue.setWindowId(window.getId());
        userQueueMapper.updateGamsUserQueue(userQueue);

        //4.修改窗口屏显示
        GamsWindowText text = windowTextMapper.findFirstByWindowId(window.getId());
        if (text != null)
        {
            text.setText("请" + userQueue.getNumber() + "办理业务");//暂停服务
            text.setInmethod(2);//静止状态
            windowTextMapper.updateGamsWindowText(text);
//
//            //另起一个线程,10秒后恢复文字
//            updateText(text);
        }
        else
        {
            log.info("找不到窗口文字:" + window.getId());
        }

        //窗口屏显示
        screenService.refreshWindowScreen(window.getWindowScreenId(), LEDSender2010.ROOT_PLAY);

        //语音播报
        sendVoice(window, userQueue);

        //更新综合屏
        sendSyncScreen(window, userQueue);
    }

    @Async
    public void updateText(GamsWindowText text)
    {
        try
        {
            Thread.sleep(10000);
        } catch (InterruptedException e)
        {
            e.printStackTrace();
        }
        text.setText(text.getDefaultText());//暂停服务
        text.setInmethod(1);//静止状态
        windowTextMapper.updateGamsWindowText(text);
    }

    private void sendSyncScreen(GamsWindow window, GamsUserQueue userQueue)
    {
        //推送目标
        Integer syncScreenId = window.getSyncScreenId();

        JSONObject res = new JSONObject();
        res.put("d", "S000001");
        res.put("c", "9");
        res.put("data", "请" + userQueue.getNumber() + "到" + userQueue.getWindowNum() + "窗口");
        ScreenVO screenVO = ScreenVO.userQueue2ScreenVO2(userQueue, 1);
        res.put("queue", screenVO);
        String msg = JSONObject.toJSONString(res);
//        log.info("msg = " + JSONObject.toJSONString(msg));
        List<GamsDevice> list = deviceMapper.selectByDepartmentId(syncScreenId);
        list.forEach(e -> socketClientStore.send(e.getDeviceId(), msg));
    }

    @Async
    public void sendVoice(GamsWindow window, GamsUserQueue userQueue)
    {
        Integer callingDeviceId = window.getCallingDeviceId();
        GamsDevice device = deviceMapper.selectGamsDeviceById(callingDeviceId);
        JSONObject res = new JSONObject();
        res.put("d", "S000001");
        res.put("c", "8");
        res.put("data", "请" + userQueue.getNumber() + "到" + userQueue.getWindowNum() + "窗口");
        String msg = JSONObject.toJSONString(res);
//        log.info("msg = " + JSONObject.toJSONString(msg));
        socketClientStore.send(device.getDeviceId(), msg);
    }
}
